package com.dayuanit.service.impl;
import java.sql.Connection;
import java.sql.SQLException;

import com.dayuanit.dao.DetailDao;
import com.dayuanit.dao.UserDao;
import com.dayuanit.domain.Detail;
import com.dayuanit.domain.User;
import com.dayuanit.service.UserService;
import com.dayuanit.util.DateBaseUtil;

public class UserServiceImpl implements UserService{

	private UserDao userDao;
	private DetailDao detailDao;

	public void openAccount(String username, String cardNum, int amount) {
		
		Connection conn = DateBaseUtil.getConn();
		if (null == conn){
			return ;
		}
		//由于connection是共享的，防止自动提交关闭，这里手动设置为true
		
		try {
			conn.setAutoCommit(false);
		}catch(SQLException sqle) {
			sqle.printStackTrace();
		}
		
		try {
			User user = new User();
			user.username = username;
			user.cardNum = cardNum;
			user.balance = amount;

			int id = userDao.add(user, conn);
			if (id == 0) {
				System.out.println("open account failed");
				conn.rollback();
				return;
			}

			user.id = id;

			//记录流水
			Detail detail = new Detail();
			detail.userId = user.id;
			detail.amount = amount;
			detail.cardNum = user.cardNum;
			detail.descMsg = "开户存钱";

			int detailId = detailDao.add(detail, conn);
			if (0 == detailId) {
				System.out.println("open account deposit failed");
				conn.rollback();
				return;
			}

			conn.commit();

		} catch(Exception e) {
			e.printStackTrace();
			try {
				conn.rollback();
			}catch(SQLException sqle){
				sqle.printStackTrace();
			}
		} finally {
			if (null != conn) {
				DateBaseUtil.close(conn);
			}
		}
		
	}

	public void deposit(String cardNum, int amount) {

		Connection conn = DateBaseUtil.getConn();
		if (null == conn){
			return ;
		}
		//存钱需要先更新余额 再插入流水 需要提供事物，将自动提交改为手动提交
		try {
			conn.setAutoCommit(false);
			User user = userDao.queryUser(cardNum, conn);
			int oldBalance = user.balance;
			
			user.balance += amount;
			int rows = userDao.modifyBalance(user.balance, oldBalance, user.id, conn);
			if (1 != rows) {
				System.out.println("deposit update balance failed");
				conn.rollback();
				return;
			}

			//记录存钱流水
			Detail detail = new Detail();
			detail.userId = user.id;
			detail.amount = amount;
			detail.cardNum = user.cardNum;
			detail.descMsg = "存钱";

			rows = detailDao.add(detail, conn);
			if (1 != rows) {
				System.out.println("deposit insert detail failed");
				conn.rollback();
				return;
			}

			conn.commit();

		}catch(SQLException sqle) {
			try {
				conn.rollback();
			}catch(SQLException e){
				e.printStackTrace();
			}

			sqle.printStackTrace();
			
		} finally {
			if (null != conn) {
				DateBaseUtil.close(conn);
			}
		}

	}

	public void draw() {

	}

	public void transfer(String inCardNum, String outCardNum, int amount) {

		if ( 0 >= amount) {
			System.out.println("金额不合法");
			return;
		}
		
		Connection conn = DateBaseUtil.getConn();
		if (null == conn){
			return ;
		}

		//TODO 根据卡号查询目标用户
		User inUser = userDao.queryUser(inCardNum, conn);
		if (null == inUser) {
			System.out.println("查无此人");
			return;
		}

		//TODO 减去自己的金额
		User outUser = userDao.queryUser(outCardNum, conn);
		
		if (null == outUser) {
			System.out.println("查无此人");
			return;
		}
		
		int oldOutBalance = outUser.balance;
		int oldInBalance = inUser.balance;

		outUser.balance -= amount;

		if (outUser.balance < 0) {
			System.out.println(Thread.currentThread().getName()  + "余额不足");
			return;
		}

		try {
			conn.setAutoCommit(false);

			System.out.println(Thread.currentThread().getName() + "正在转账");
			int rows = userDao.modifyBalance(outUser.balance, oldOutBalance, outUser.id, conn);
			if (rows == 0) {
				System.out.println(Thread.currentThread().getName() + "转账失败");
				try {
					conn.rollback();
				} catch(SQLException sqle) {
					sqle.printStackTrace();
				}

				return;
			}

			
			Thread.sleep(10 * 1000);
			System.out.println(Thread.currentThread().getName() + "可以转账");

			//TODO 增加目标金额
			inUser.balance += amount;
			rows = userDao.modifyBalance(inUser.balance, oldInBalance, inUser.id, conn);
			if (0 == rows) {
				System.out.println(Thread.currentThread().getName() + "转账失败");
				try {
					conn.rollback();
				} catch(SQLException sqle) {
					sqle.printStackTrace();
				}

				return;
			}

			//TODO 增加两个交易流水
			Detail outDetail = new Detail();
			outDetail.userId = outUser.id;
			outDetail.amount = amount;
			outDetail.cardNum = outUser.cardNum;
			outDetail.descMsg = "转账支出";
			rows = detailDao.add(outDetail, conn);
			if (0 == rows) {
				System.out.println("转账失败，流水插入失败");
				try {
					conn.rollback();
				} catch(SQLException sqle) {
					sqle.printStackTrace();
				}
				return;
			}

			Detail inDetail = new Detail();
			inDetail.userId = inUser.id;
			inDetail.amount = amount;
			inDetail.cardNum = inUser.cardNum;
			inDetail.descMsg = "转账收入";
			rows = detailDao.add(inDetail, conn);
			if (0 == rows) {
				System.out.println("转账失败，流水插入失败");
				try {
					conn.rollback();
				} catch(SQLException sqle) {
					sqle.printStackTrace();
				}
				return;
			}

			conn.commit();
		} catch(Exception e) {
			try {
				conn.rollback();
			} catch(SQLException sqle) {
				sqle.printStackTrace();
			}
			e.printStackTrace();
		} finally {
			if (null != conn) {
				DateBaseUtil.close(conn);
			}
		}

	}

	public int queryBalance(String cardNum) {
		Connection conn = DateBaseUtil.getConn();
		if (null == conn){
			return 0;
		}
		
		try {
			User user = userDao.queryUser(cardNum, conn);
			return user.balance;
		} finally {
			if (null != conn) {
				DateBaseUtil.close(conn);
			}
		}
		
	}

	public void queryDetails() {

	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public void setDetailDao(DetailDao detailDao) {
		this.detailDao = detailDao;
	}

}